 <template>
  <div class="activity-post-editor">
    <textarea v-model="content" placeholder="说点什么..." class="editor-textarea"></textarea>
    <div class="topic-selector" style="margin-bottom: 12px; display: flex; align-items: center; gap: 10px;">
      <button class="black-btn" style="width: 100px; padding: 8px 0; margin-bottom: 0;" @click="showNewTopicModal = true">新建话题</button>
      <select v-model="selectedTopicId" class="topic-select">
        <option value="" disabled>请选择话题</option>
        <option v-for="topic in topics" :key="topic.id" :value="topic.id">
          {{ topic.content }}
        </option>
      </select>
    </div>
    <div class="row-flex">
      <div class="media-upload-plus" @click="triggerFileInput">
        <span class="plus-icon">+</span>
        <input type="file" ref="fileInput" multiple accept="image/*,video/*" @change="handleFileUpload" style="display:none" />
      </div>
      <div class="visibility-selector">
        <div class="selected-visibility" @click="toggleVisibilityMenu">
          <i :class="visibilityIcon"></i>
          <span>{{ visibilityText }}</span>
          <i class="fas fa-chevron-down"></i>
        </div>
        <div class="visibility-menu" v-show="showVisibilityMenu">
          <div
            class="visibility-option"
            v-for="option in visibilityOptions"
            :key="option.value"
            @click="selectVisibility(option.value)"
            :class="{ active: visibility === option.value }"
          >
            <i :class="option.icon"></i>
            {{ option.label }}
          </div>
        </div>
      </div>
    </div>
    <div class="media-preview">
      <div v-for="(media, idx) in mediaList" :key="idx" class="media-thumb">
        <img v-if="media.type==='image'" :src="media.preview" />
        <video v-else controls :src="media.preview" />
        <button class="black-btn remove-btn" @click="removeMedia(idx)">移除</button>
      </div>
    </div>
    <button class="black-btn publish-btn-bottom" @click="submitPost" :disabled="isLoading || !userId || userId === 4">{{ isLoading ? '发布中...' : '发布' }}</button>
    <div v-if="!userId || userId === 4" style="color:#e74c3c;margin-top:8px;">请先登录后再发布动态</div>
    <!-- 新建话题弹窗 -->
    <div v-if="showNewTopicModal" class="modal-overlay" @click.self="showNewTopicModal = false">
      <div class="modal-content">
        <button class="close-modal-btn" @click="showNewTopicModal = false">退出新建话题</button>
        <div class="activity-post-editor" style="box-shadow:none;max-width:400px;padding:24px 24px 12px 24px;">
          <input v-model="newTopicContent" placeholder="输入新话题..." class="topic-input" />
          <button class="black-btn" style="margin-top:18px;" @click="createTopic" :disabled="isCreatingTopic">{{ isCreatingTopic ? '创建中...' : '确定' }}</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue';
import axios from 'axios';

const props = defineProps({
  activity: { type: Object, default: null } // 编辑时传入
});
const emit = defineEmits(['success', 'close']);

const content = ref(props.activity ? props.activity.content : '');
const visibility = ref(props.activity ? props.activity.visibility : 0);
const mediaList = ref([]); // {file, preview, type}
const isLoading = ref(false);
const fileInput = ref(null);
const showVisibilityMenu = ref(false);
const topics = ref([]);
const selectedTopicId = ref('');
const showNewTopicModal = ref(false);
const newTopicContent = ref('');
const isCreatingTopic = ref(false);
const userId = ref(Number(localStorage.getItem('userId')) || null);

/**
 * 监听 localStorage 的变化，自动更新当前用户 ID。
 */
window.addEventListener('storage', () => {
  userId.value = Number(localStorage.getItem('userId')) || null;
});

/**
 * 可见性选项配置
 */
const visibilityOptions = [
  { value: 0, label: '所有人可见', icon: 'fas fa-globe' },
  { value: 1, label: '好友可见', icon: 'fas fa-user-friends' },
  { value: 2, label: '仅自己可见', icon: 'fas fa-lock' }
];

/**
 * 计算当前选择的可见性文本描述
 */
const visibilityText = computed(() => {
  return visibilityOptions.find(o => o.value === visibility.value)?.label || '';
});

/**
 * 计算当前选择的可见性图标类名
 */
const visibilityIcon = computed(() => {
  return visibilityOptions.find(o => o.value === visibility.value)?.icon || '';
});

/**
 * 初始化媒体列表（编辑模式下）
 */
if (props.activity && props.activity.mediaUrls) {
  try {
    const arr = parseImages(props.activity.mediaUrls);
    arr.forEach(url => {
      mediaList.value.push({ preview: url, type: url.match(/\.(mp4|webm|ogg)$/i) ? 'video' : 'image', file: null });
    });
  } catch (e) { /* empty */ }
}

/**
 * 组件挂载后获取话题列表
 */
onMounted(async () => {
  try {
    const response = await axios.get('http://localhost:8085/topics');
    topics.value = response.data;
  } catch (e) {
    topics.value = [];
  }
});

/**
 * 触发文件输入框点击事件
 */
function triggerFileInput() {
  fileInput.value.click();
}

/**
 * 处理文件上传事件，将文件读取为预览 URL 并添加到媒体列表中
 * @param {Event} e - 文件选择事件对象
 */
function handleFileUpload(e) {
  const files = Array.from(e.target.files);
  files.forEach(file => {
    const reader = new FileReader();
    reader.onload = ev => {
      mediaList.value.push({ file, preview: ev.target.result, type: file.type.startsWith('video') ? 'video' : 'image' });
    };
    reader.readAsDataURL(file);
  });
}

/**
 * 移除指定索引位置的媒体项
 * @param {number} idx - 要移除的媒体在 mediaList 中的索引
 */
function removeMedia(idx) {
  mediaList.value.splice(idx, 1);
}

/**
 * 切换可见性菜单显示状态
 */
function toggleVisibilityMenu() {
  showVisibilityMenu.value = !showVisibilityMenu.value;
}

/**
 * 选择并设置可见性，并关闭菜单
 * @param {number} value - 要设置的可见性值
 */
function selectVisibility(value) {
  visibility.value = value;
  showVisibilityMenu.value = false;
}

/**
 * 解析 mediaUrls 字符串为数组
 * @param {string|Array} mediaUrls - 媒体 URL 字符串或数组
 * @returns {Array} 解析后的媒体 URL 数组
 */
function parseImages(mediaUrls) {
  if (!mediaUrls) return [];
  try {
    return Array.isArray(mediaUrls) ? mediaUrls : JSON.parse(mediaUrls);
  } catch {
    return [];
  }
}

/**
 * 提交动态内容到服务器
 */
async function submitPost() {
  if (!content.value && !mediaList.value.length) return;

  // 用户ID校验
  if (!userId.value || userId.value === 4) {
    alert('用户未登录或游客账号，无法发布动态');
    return;
  }

  isLoading.value = true;

  try {
    // 上传媒体文件到后端，获取七牛云外链
    const uploadedUrls = [];
    for (const media of mediaList.value) {
      if (media.file) {
        const formData = new FormData();
        formData.append('file', media.file);
        const response = await axios.post('http://localhost:8085/activity/upload', formData);
        uploadedUrls.push(response.data); // 后端返回的七牛云外链
      } else {
        uploadedUrls.push(media.preview); // 已有外链
      }
    }

    const data = {
      content: content.value,
      mediaUrls: JSON.stringify(uploadedUrls),
      visibility: visibility.value,
      userId: userId.value,
      likesCount: 0,
      commentNum: 0,
      createDate: new Date(),
      updateDate: new Date(),
      isDeleted: 0,
      version: 1,
      topicId: selectedTopicId.value
    };

    if (props.activity && props.activity.id) {
      // 编辑逻辑
      await axios.put(`/activity/${props.activity.id}`, { ...props.activity, ...data });

      // 如果话题发生变化，处理话题计数变化
      if (props.activity.topicId !== selectedTopicId.value) {
        // 减少旧话题计数
        if (props.activity.topicId) {
          try {
            await axios.post(`http://localhost:8085/topics/${props.activity.topicId}/decrement`);
          } catch (e) {
            console.error('减少旧话题计数失败:', e);
          }
        }

        // 增加新话题计数
        if (selectedTopicId.value) {
          try {
            await axios.post(`http://localhost:8085/topics/${selectedTopicId.value}/increment`);
          } catch (e) {
            console.error('增加新话题计数失败:', e);
          }
        }
      }
    } else {
      // 新增逻辑
      await axios.post('/activity', data);

      // 如果选择了话题，增加话题计数
      if (selectedTopicId.value) {
        try {
          await axios.post(`http://localhost:8085/topics/${selectedTopicId.value}/increment`);
        } catch (e) {
          console.error('增加话题计数失败:', e);
        }
      }
    }

    // 发送成功事件，总是包含刷新标志
    emit('success', { refresh: true });
    emit('close');
  } catch (e) {
    alert('发布失败');
  } finally {
    isLoading.value = false;
  }
}

/**
 * 创建新话题并刷新话题列表
 */
async function createTopic() {
  if (!newTopicContent.value.trim()) return;

  isCreatingTopic.value = true;

  try {
    await axios.post('http://localhost:8085/topics', { content: newTopicContent.value });

    // 刷新话题列表并选中新建话题
    const topicRes = await axios.get('http://localhost:8085/topics');
    topics.value = topicRes.data;

    // 自动选中新建话题
    const created = topics.value.find(t => t.content === newTopicContent.value);
    if (created) selectedTopicId.value = created.id;

    showNewTopicModal.value = false;
    newTopicContent.value = '';
  } catch (e) {
    alert('新建话题失败');
  } finally {
    isCreatingTopic.value = false;
  }
}
</script>


<style scoped>
.activity-post-editor {
  background: #fff;
  padding: 32px 40px 28px 40px;
  border-radius: 16px;
  box-shadow: 0 4px 24px rgba(44,62,80,0.13);
  width: 100%;
  max-width: 600px;
  box-sizing: border-box;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 18px;
  height: auto;
  max-height: 90vh;
  overflow-y: auto;
  overflow-x: hidden;
}
.editor-textarea {
  width: 100%;
  min-height: 80px;
  max-height: 220px;
  background: #f8f9fa;
  color: #23232b;
  border-radius: 10px;
  border: 1.5px solid #e0e0e0;
  padding: 16px 18px;
  font-size: 17px;
  line-height: 1.8;
  resize: vertical;
  margin-bottom: 18px;
  box-sizing: border-box;
  overflow-y: auto;
  transition: border 0.2s, background 0.2s;
}
.editor-textarea:focus {
  border: 1.5px solid #3498db;
  background: #f5f6fa;
  outline: none;
}
.editor-textarea::placeholder {
  color: #bfc3c9;
  font-size: 16px;
}
.row-flex {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  margin-bottom: 18px;
}
.media-upload-plus {
  width: 90px;
  height: 90px;
  background: #fafbfc;
  border-radius: 14px;
  border: 1.5px solid #f3f4f6;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: border 0.2s, box-shadow 0.2s, background 0.2s;
  box-shadow: 0 1px 4px rgba(44,62,80,0.04);
  flex-shrink: 0;
}
.media-upload-plus:hover {
  border: 1.5px solid #3498db;
  background: #f0f6ff;
  box-shadow: 0 2px 8px rgba(52,152,219,0.10);
}
.plus-icon {
  font-size: 38px;
  color: #c3c8d1;
  font-weight: 400;
  user-select: none;
}
.visibility-selector {
  min-width: 160px;
  max-width: 220px;
  flex: 1;
  margin-bottom: 0;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}
.selected-visibility {
  min-width: 140px;
  max-width: 220px;
  width: 100%;
  height: 48px;
  box-sizing: border-box;
  border: 1px solid #e0e0e0;
  border-radius: 14px;
  padding: 0 18px;
  background: #fafbfc;
  color: #23232b;
  display: flex;
  align-items: center;
  cursor: pointer;
  font-size: 17px;
  margin-bottom: 0;
  transition: border 0.2s, background 0.2s;
  position: relative;
}
.selected-visibility i.fas.fa-chevron-down {
  margin-left: auto;
  font-size: 15px;
  color: #bfc3c9;
}
.selected-visibility:hover, .selected-visibility:focus {
  border: 1px solid #bfc3c9;
  background: #f5f6fa;
}
.visibility-menu {
  min-width: 140px;
  max-width: 220px;
  right: auto;
  left: 0;
  width: 100%;
  box-sizing: border-box;
  position: absolute;
  border: 1px solid #e0e0e0;
  border-radius: 16px;
  background: #fff;
  margin-top: 6px;
  box-shadow: 0 8px 32px rgba(44,62,80,0.10);
  overflow: hidden;
  z-index: 10;
}
.visibility-option {
  color: #23232b !important;
  padding: 14px 20px;
  cursor: pointer;
  border-radius: 0;
  font-size: 17px;
  transition: background 0.2s, color 0.2s;
  text-align: left;
  background: #fff;
}
.visibility-option.active, .visibility-option:hover {
  color: #23232b !important;
  background: #f5f6fa;
  font-weight: bold;
}
.black-btn, .publish-btn-bottom {
  background: linear-gradient(135deg, #43484e, #23272b);
  color: #fff;
  border: none;
  border-radius: 18px;
  box-shadow: 0 4px 16px rgba(52,152,219,0.10);
  font-size: 18px;
  font-weight: 500;
  padding: 14px 0;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  margin-bottom: 18px;
  transition: background 0.2s, box-shadow 0.2s;
}
.black-btn:disabled, .publish-btn-bottom:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  background: #ccc;
}
.black-btn:not(:disabled):hover, .publish-btn-bottom:not(:disabled):hover {
  background: linear-gradient(135deg, #23272b, #43484e);
  box-shadow: 0 6px 24px rgba(52,152,219,0.16);
}
.media-preview {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}
.media-thumb img, .media-thumb video {
  max-width: 120px;
  max-height: 120px;
  border-radius: 6px;
  box-shadow: 0 1px 4px rgba(44,62,80,0.10);
}
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal-content {
  background: #fff;
  border-radius: 16px;
  box-shadow: 0 4px 24px rgba(44, 62, 80, 0.13);
  padding: 24px;
  width: 90%;
  max-width: 400px;
  margin: 0 auto;
}

.close-modal-btn {
  margin-bottom: 18px !important;
  background: none;
  border: none;
  color: #b0b3c6;
  font-size: 16px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  border-radius: 6px;
  padding: 4px 10px;
  transition: background 0.2s, color 0.2s;
}

.close-modal-btn:hover {
  background: #f0f2f5;
  color: #3498db;
}
.close-modal-btn {
  margin-bottom: 36px !important;
}

.topic-selector {
  width: 100%;
  margin-bottom: 12px;
}
.topic-select {
  width: 100%;
  padding: 10px 14px;
  border-radius: 10px;
  border: 1.5px solid #e0e0e0;
  font-size: 16px;
  background: #fafbfc;
  color: #23232b;
  margin-bottom: 0;
  box-sizing: border-box;
}
.topic-input {
  width: 100%;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1.5px solid #e0e0e0;
  font-size: 16px;
  background: #fafbfc;
  color: #23232b;
  margin-bottom: 0;
  box-sizing: border-box;
}
</style> 